package com.df.excel_export.simple_export;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.fastjson.JSON;
import com.df.excel_export.SimpleExport;
import freemarker.template.Template;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

public class SimpleHTableReaderListener implements ReadListener<Map<Integer, String>> {

    int row = 1;
    int dataRow = 0;
    String tableZhName;
    List<String> fields = new ArrayList<>();
    List<String> types = new ArrayList<>();
    List<String> desc = new ArrayList<>();

    private String dataFilePath = "";
    private String codeFilePath = "";

    private List<List<String>> finallyField = new ArrayList<>();
    //注解
    List<String> commons = new ArrayList<>();
    //[{fieldName:[type(string),value(object)]}]
    List<Map<String,Object>> rowDatas = new ArrayList<>();

    public SimpleHTableReaderListener(String dataFilePath, String codeFilePath) {
        this.dataFilePath = dataFilePath;
        this.codeFilePath = codeFilePath;
    }

    @Override
    public void invoke(Map<Integer, String> map, AnalysisContext context) {
        Integer rowIndex = context.readRowHolder().getRowIndex();
        row = rowIndex + 1;
        //header
        if(row==1){
            dataRow = Integer.valueOf(map.get(1));
            tableZhName = map.get(2);
            return;
        }
        //表头解析
        if(row<dataRow){
            String headerName = map.get(0);
            if(headerName==null || headerName.equals("")){
                return;
            }
            if (headerName.equals("field")) {
                for (int i = 1; i < map.size(); i++) {
                    fields.add(map.get(i));
                }
            }
            if (headerName.equals("type")) {
                for (int i = 1; i < map.size(); i++) {
                    types.add(map.get(i));
                }
            }
            if (headerName.equals("desc")) {
                for (int i = 1; i < map.size(); i++) {
                    desc.add(map.get(i));
                }
            }

            return;
        }

        if(dataRow==0 || row<dataRow){
            return;
        }
        if(fields.size()!=types.size() && fields.size()!=desc.size()){
            //补齐
            int maxSize = fields.size();
//            maxSize = Math.max(maxSize,group.size());
            maxSize = Math.max(maxSize,desc.size());
            if(fields.size()<maxSize){
                for (int i = 0; i < maxSize-fields.size(); i++) {
                    fields.add(null);
                }
            }
            if(types.size()<maxSize){
                for (int i = 0; i < maxSize-types.size(); i++) {
                    types.add(null);
                }
            }
            if(desc.size()<maxSize){
                for (int i = 0; i < maxSize-desc.size(); i++) {
                    desc.add(null);
                }
            }
        }
        if(finallyField.isEmpty()){
            int size = fields.size();

            for (int i = 0; i < size; i++) {
                String field = fields.get(i);
                if(field==null || field.isEmpty()){
                    continue;
                }
                String type = types.get(i);
                if(type==null || type.isEmpty()){
                    continue;
                }
                String de = desc.get(i);
                if(de==null || de.isEmpty()){
                    continue;
                }
                List<String> finalField = new ArrayList<>();
                finalField.add(field);
                finalField.add(type);
                finalField.add(de);
                if(!finalField.isEmpty()){
                    finallyField.add(finalField);
                }
            }

        }

        //数据行开始解析
        Map<String,Object> rowData = new HashMap<>();
        boolean skip = false;
        int size = fields.size();
        for (int i = 0; i < size; i++) {
            String field = fields.get(i);
            if(field==null || field.isEmpty()){
                continue;
            }
            String type = types.get(i);
            if(type==null || type.isEmpty()){
                continue;
            }
            String de = desc.get(i);
            if(de==null || de.isEmpty()){
                continue;
            }
            String valueStr = map.get(i+1);
            if((valueStr==null ||valueStr.isEmpty()) && i==0){
                skip = true;
                break;
            }
            Object vObj = handleValue(type,valueStr,row,i+1);
            rowData.put(field,vObj);
        }
        if(!skip){
            rowDatas.add(rowData);
        }
    }

    private Object handleValue(String type, String valueStr, int row, int col) {
        Object vObj = null;
        try {
            if(type.equals("int")){
                if(valueStr==null || valueStr.isEmpty()){
                    vObj = 0;
                }else {
                    vObj = Integer.parseInt(valueStr);
                }
            }
            if(type.equals("int[]")){//1:2:3
                if(valueStr==null || valueStr.isEmpty()){
                    vObj = new ArrayList<Integer>();
                }else {
                    String[] split = valueStr.split(":");
                    List<Integer> list = new ArrayList<>();
                    for (String s : split) {
                        list.add(Integer.parseInt(s));
                    }
                    vObj = list;
                }

            }
            if(type.equals("int[][]")){//1:2:3|2:3:3
                if(valueStr==null || valueStr.isEmpty()){
                    vObj = new ArrayList<Integer>();
                }else {
                    List<List<Integer>> list = new ArrayList<>();
                    String[] outer = valueStr.split("\\|");
                    for (String os : outer) {
                        String[] split = os.split(":");
                        List<Integer> inList = new ArrayList<>();
                        for (String in : split) {
                            inList.add(Integer.parseInt(in));
                        }
                        list.add(inList);
                    }
                    vObj = list;
                }
            }
            if(type.equals("string")){
                if(valueStr==null || valueStr.isEmpty()){
                    vObj = "";
                }else {
                    vObj = valueStr;
                }
            }
            if(type.equals("string[]")){
                if(valueStr==null || valueStr.isEmpty()){
                    vObj = new ArrayList<String>();
                }else {
                    String[] split = valueStr.split(":");
                    List<String> list = new ArrayList<>();
                    for (String s : split) {
                        list.add(s);
                    }
                    vObj = list;
                }
            }
            if(type.equals("string[][]")){
                if(valueStr==null || valueStr.isEmpty()){
                    vObj = new ArrayList<String>();
                }else {
                    List<List<String>> list = new ArrayList<>();
                    String[] outer = valueStr.split("\\|");
                    for (String os : outer) {
                        String[] split = os.split(":");
                        List<String> inList = new ArrayList<>();
                        for (String in : split) {
                            inList.add(in);
                        }
                        list.add(inList);
                    }
                    vObj = list;
                }
            }
        }catch (Exception e) {
            System.out.println("解析失败，row:"+row+" col:"+col+" type:"+type+" value:"+valueStr);
            e.printStackTrace();
        }

        return vObj;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        String sheetName = analysisContext.readSheetHolder().getSheetName();
        String dataFileName = sheetName.replace("t_", "");
        String className = dataFileName.substring(0,1).toUpperCase()+dataFileName.substring(1);
        Map<String,Object> data = new HashMap<>();
        data.put("tableName", tableZhName);
        data.put("file", analysisContext.readWorkbookHolder().getFile().getAbsolutePath());
        data.put("sheet", sheetName);
        data.put("className", className);
        data.put("dataFileName", dataFileName);
        data.put("fields", finallyField);
        //按模板导出bean
        String beanCodePath = codeFilePath+File.separator+className+"Cfg.ts";
        Template template = null;
        try {
            template = SimpleExport.configuration.getTemplate("front_bean.ftl");
            // 第六步：创建一个Writer对象，一般创建一FileWriter对象，指定生成的文件名。
            Writer out = new FileWriter(new File(beanCodePath));
            // 第七步：调用模板对象的process方法输出文件。
            template.process(data, out);
            // 第八步：关闭流。
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //按模板导出root管理器
        String rooCodePath = codeFilePath+File.separator+className+"CfgRoot.ts";

        try {
            template = SimpleExport.configuration.getTemplate("front_bean_root.ftl");
            // 第六步：创建一个Writer对象，一般创建一FileWriter对象，指定生成的文件名。
            Writer out = new FileWriter(new File(rooCodePath));
            // 第七步：调用模板对象的process方法输出文件。
            template.process(data, out);
            // 第八步：关闭流。
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //json数据
        String dataStr = JSON.toJSONString(rowDatas, true);
//        String dataStr = JSON.toJSONString(rowDatas);
        File file = new File(dataFilePath+File.separator+dataFileName+".json");
        try(
                BufferedWriter bw = new BufferedWriter(new FileWriter(file));
                ) {
            bw.write(dataStr);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}
